package com.qcrud.core.paging;

import com.qcrud.core.SqlData;
import com.qcrud.core.datasource.DbType;
import com.qcrud.core.paging.dialects.IDialect;
import com.qcrud.core.paging.dialects.MySqlDialect;
import com.qcrud.core.paging.dialects.OracleDialect;
import com.qcrud.core.paging.dialects.PostgresqlDialect;
import com.qcrud.tookit.ExceptionUtils;

import java.util.EnumMap;
import java.util.Map;

/**
 * 分页方言工厂类
 */
public class DialectFactory {
    private static final Map<DbType, IDialect> DIALECT_ENUM_MAP = new EnumMap<>(DbType.class);

    public static void buildSql(SqlData sqlData) {
        Paging paging = sqlData.getPaging();
        if (null != paging) {
            sqlData.setSql(getDialect(sqlData.getCtx().getDbType())
                    .buildSql(sqlData.getSql(), paging.offset(), paging.getSize()));
        }
    }

    public static IDialect getDialect(DbType dbType) {
        IDialect dialect = DIALECT_ENUM_MAP.get(dbType);
        if (null == dialect) {
            if (dbType == DbType.OTHER) {
                throw ExceptionUtils.mpe("%s database not supported.", dbType.getDb());
            }
            // mysql same type
            else if (dbType == DbType.MYSQL
                    || dbType == DbType.MARIADB
                    || dbType == DbType.GBASE
                    || dbType == DbType.OSCAR
                    || dbType == DbType.XU_GU
                    || dbType == DbType.CLICK_HOUSE
                    || dbType == DbType.OCEAN_BASE
                    || dbType == DbType.CUBRID
                    || dbType == DbType.GOLDILOCKS
                    || dbType == DbType.CSIIDB) {
                dialect = new MySqlDialect();
            }
            // oracle same type
            else if (dbType == DbType.ORACLE
                    || dbType == DbType.DM
                    || dbType == DbType.GAUSS) {
                dialect = new OracleDialect();
            }
            // postgresql same type
            else if (dbType == DbType.POSTGRE_SQL
                    || dbType == DbType.H2
                    || dbType == DbType.SQLITE
                    || dbType == DbType.HSQL
                    || dbType == DbType.KINGBASE_ES
                    || dbType == DbType.PHOENIX
                    || dbType == DbType.SAP_HANA
                    || dbType == DbType.IMPALA
                    || dbType == DbType.HIGH_GO
                    || dbType == DbType.VERTICA) {
                dialect = new PostgresqlDialect();
            }
            DIALECT_ENUM_MAP.put(dbType, dialect);
        }
        return dialect;
    }
}
